package util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.hibernate.Session;
import org.hibernate.Transaction;

import domain.entities.interfaces.IAddress;
import domain.entities.interfaces.IContact;
import domain.entities.interfaces.IEntreprise;

public class DomainUtils {

	/**
	 * The request attribute name to use for get error in servlets.
	 */
	public static final String ALERT_ERROR_STRING = "alert_error";

	/**
	 * The request attribute name to use for get info in servlets.
	 */
	public static final String ALERT_INFO_STRING_1 = "alert_info_1";

	/**
	 * The request attribute name to use for get info in servlets.
	 */
	public static final String ALERT_INFO_STRING_2 = "alert_info_2";

	/**
	 * The session attribute name to use for get current user in servlets.
	 */
	public static final String CURRENT_USER_STRING = "current_user";

	/**
	 * The request attribute name to use for get search contact result in servlets.
	 */
	public static final String SEARCH_CONTACT_RESULT = "search_contact_result";

	/**
	 * The request attribute name to use for get search contact result in servlets.
	 */
	public static final String SEARCH_CONTACT_GROUP_RESULT = "search_contact_group_result";

	
	/**
	 * The session attribute name to use for change the color of the alert for 
	 * multi-register alert-info
	 */
	public static final String REGISTER_ALERT_CURRENT_COLOR = 
			"register_alert_current_color";

	/**
	 * The session attribute name to use for change the color of the alert for 
	 * multi-add-contact alert-info
	 */
	public static final String ADD_CONTACT_ALERT_CURRENT_COLOR = 
			"add_contact_alert_current_color";

	/**
	 * The session attribute name to use for change the color of the alert for
	 *  multi-add-contact-group alert-info
	 */
	public static final String ADD_CONTACT_GROUP_ALERT_CURRENT_COLOR = 
			"add_contact_group_alert_current_color";

	/**
	 * The session attribute name to use for change the color of the alert for 
	 * multi-action in show contact view alert-info
	 */
	public static final String SHOW_CONTACT_ALERT_CURRENT_COLOR = 
			"show_contact_alert_current_color";

	/**
	 * The session attribute name to use for change the color of the alert for 
	 * multi-action in show contact group view alert-info
	 */
	public static final String SHOW_CONTACT_GROUP_ALERT_CURRENT_COLOR = 
			"show_contact_group_alert_current_color";
	
	/**
	 * The session attribute name to use for change the color of the alert for 
	 * multi-update alert-info
	 */
	public static final String UPDATE_CONTACT_ALERT_CURRENT_COLOR = 
			"update_contact_alert_current_color";

	private static final String COLOR_1 = "color_1";
	private static final String COLOR_2 = "color_2";


	public static String getNotNullValue(
			ServletRequest request, String attributeName) {

		String errorMessage = (String)request.getAttribute(attributeName);
		return (errorMessage == null) ? "" : errorMessage;
	}

	public static boolean isNumber(String str) {

		try {
			Integer.parseInt(str);
			return true;
		}
		catch(Exception e) { }

		try {
			Double.parseDouble(str);
			return true;
		}
		catch(Exception e) { }

		return false;
	}

	public static boolean startByADigital(String str) {
		return isNumber(str.substring(0, 1));
	}

	public static boolean startByALetter(String str) {

		if(str == null || str.isEmpty()) {
			return false;
		}

		return match(str.substring(0, 1), "[a-zA-Z]");
	}

	public static boolean startByUnderscore(String str) {

		if(str == null || str.isEmpty()) {
			return false;
		}

		return match(str.substring(0, 1), "_");
	}

	public static boolean containsALetter(String str) {

		if(str == null || str.isEmpty()) {
			return false;
		}

		return str.replaceAll("[a-zA-Z]", "").length() < str.length();
	}

	public static boolean match(String expression, String pattern) {
		String tmp = expression.replaceAll(pattern, "");
		System.out.println("Voici ce qu'il reste : " + tmp);
		System.out.println("Longueur de la chaine : " + tmp.length());
		return tmp.isEmpty() == true;
	}

	public static <T> List<T> castList(Class<? extends T> clazz, Collection<?> c) {
		List<T> r = new ArrayList<T>(c.size());
		for(Object o: c)
			r.add(clazz.cast(o));
		return r;
	}

	public static String displayContact(IContact c) {
		
		IAddress add = c.getAdd();
		String result = "";

		result += c.getFirstName()+" ";
		result += c.getLastName()+ " at ";
		result += add.getStreet()+" ";
		result += add.getCity()+", ";
		result += add.getZip()+ " ";
		result += add.getCountry()+" ";
		
		if(c instanceof IEntreprise) {
			result += "(Enterprise)";
		}
		
		return result;
	}

	public static void displayInfoMessage(HttpServletRequest request, String alertCurrentColor, String message) {

		HttpSession session = request.getSession(false);
		String currentInfoColor = (String)session.getAttribute(alertCurrentColor);

		if(currentInfoColor != null && currentInfoColor.compareTo(COLOR_1) == 0) {
			request.setAttribute(ALERT_INFO_STRING_2, message);
			session.setAttribute(alertCurrentColor, COLOR_2);
		}
		else {
			request.setAttribute(ALERT_INFO_STRING_1, message);
			session.setAttribute(alertCurrentColor, COLOR_1);
		}
	}

	public static void keepParametersContent(HttpServletRequest request) {
		
		Enumeration<String> parametersNames = request.getParameterNames();
		
		while(parametersNames.hasMoreElements()) {
			
			String parameterName = parametersNames.nextElement();
			
			request.setAttribute(
					parameterName, 
					request.getParameter(parameterName));
		}
	}

	/**
	 * Used within DAOs methods to check hibernateSession that Servlets
	 * give to them. This session acte as a flag to inform them that they are 
	 * include in a more big transaction and that it's not necessary for them to 
	 * start another one.
	 * 
	 * @param currentHibernateSession
	 * @param transaction
	 * @throws Exception 
	 */
	public static Boolean isInSuperTransaction(Session currentHibernateSession){
		return (currentHibernateSession != null);
	}

	public static String trim(String str) {
		return (str == null) ? null : str.trim();
	}

}
